home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: draw.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
- *
- * $Date: 2000/04/07 19:44:51 $
- * $Revision: 1.1.1.1 $
- *
- * (C) 1999 by Hyperion
- * All rights reserved
- *
- * This file is part of the MiniGL library project
- * See the file Licence.txt for more details
- *
- */
-
- #include "sysinc.h"
- #include <math.h>
- #include <stdlib.h>
-
- static char rcsid[] = "$Id: draw.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
-
- #define DUMP_VERTEX(vert) \
- mykprintf("x:%6.3f y:%6.3f z:%6.3f w:%6.3f\nR:%6.3f G:%6.3f B:%6.3f A:%6.3f\nU:%6.3f V:%6.3f\noutcode=0x%x\n",\
- vert.bx, vert.by, vert.bz, vert.bw, \
- vert.v.color.r, vert.v.color.g, vert.v.color.b, vert.v.color.a, \
- vert.v.u, vert.v.v, vert.outcode)
-
- #define DUMP_VERTEX2(vert) \
- mykprintf("X:%6.3f Y:%6.3f Z:%6.3f W:%6.3f\nR:%6.3f G:%6.3f B:%6.3f A:%6.3f\nU:%6.3f V:%6.3f\n",\
- vert.x, vert.y, vert.z, vert.w, \
- vert.color.r, vert.color.g, vert.color.b, vert.color.a, \
- vert.u, vert.v); \
-
-
- void d_DrawPoly(GLcontext context, MGLPolygon *poly);
- void dh_DrawPolyFF(GLcontext context, MGLPolygon *poly);
- void d_DrawPolyExt(GLcontext context, MGLPolygon *poly);
- void d_DrawPoints (GLcontext);
- void d_DrawLines (GLcontext);
- void d_DrawLineStrip (GLcontext);
- void d_DrawTriangles (GLcontext);
- void d_DrawTriangleFan (GLcontext);
- void d_DrawTriangleStrip (GLcontext);
- void d_DrawQuads (GLcontext);
- void d_DrawPolygon (GLcontext);
- void d_DrawFlatFan (GLcontext);
- void d_DrawQuadStrip (GLcontext);
-
- INLINE void v_ApplyMatrixElCheapo(GLcontext context, Matrix *pA, int vnum);
- INLINE GLvoid v_Transform(GLcontext context);
- INLINE void v_ToScreen(GLcontext context, int i);
- void m_CombineMatrices(GLcontext context);
-
- extern void m_BuildInverted(GLcontext context);
- extern void hc_ClipAndDrawPolyFF(GLcontext context, MGLPolygon *poly, GLubyte or_codes);
-
-
- INLINE void v_ApplyMatrixElCheapo(GLcontext context, Matrix *pA, int vnum)
- {
- // El Cheapo implementation ATM
- #define a(x) (pA->v[OF_##x])
- float x=context->VertexBuffer[vnum].bx;
- float y=context->VertexBuffer[vnum].by;
- float z=context->VertexBuffer[vnum].bz;
- float w=context->VertexBuffer[vnum].bw;
-
- if (pA->flags == MGLMAT_IDENTITY) return;
- context->VertexBuffer[vnum].bx = a(11)*x + a(12)*y + a(13)*z + a(14)*w;
- context->VertexBuffer[vnum].by = a(21)*x + a(22)*y + a(23)*z + a(24)*w;
- context->VertexBuffer[vnum].bz = a(31)*x + a(32)*y + a(33)*z + a(34)*w;
- context->VertexBuffer[vnum].bw = a(41)*x + a(42)*y + a(43)*z + a(44)*w;
-
- return;
- #undef a
- }
-
-
- INLINE void v_ApplyMatrixWOne(GLcontext context, Matrix *pA, int vnum)
- {
- // W assumed to be 1.0
- #define a(x) (pA->v[OF_##x])
- float x=context->VertexBuffer[vnum].bx;
- float y=context->VertexBuffer[vnum].by;
- float z=context->VertexBuffer[vnum].bz;
-
- context->VertexBuffer[vnum].bx = a(11)*x + a(12)*y + a(13)*z + a(14);
- context->VertexBuffer[vnum].by = a(21)*x + a(22)*y + a(23)*z + a(24);
- context->VertexBuffer[vnum].bz = a(31)*x + a(32)*y + a(33)*z + a(34);
- context->VertexBuffer[vnum].bw = a(41)*x + a(42)*y + a(43)*z + a(44);
-
- return;
- #undef a
- }
-
-
- /*
- ** This computationally intensive piece of code generates coordinates
- ** for the reflective image used in spherical environment mapping.
- ** This is a good place for optimizations.
- ** After generation, transforms into the clipping space...
- **
- ** Note that this is after the book. It is probably a big time-eater.
- **
- ** (Turned out not to be so time intensive after all...)
- */
- void v_GenTexCoords(GLcontext context, int vertex)
- {
- float u[4];
- float ul;
- float nx,ny,nz;
- float nu;
- float rx,ry,rz;
- float m;
- float s,t;
-
- if (context->InvRotValid == GL_FALSE) m_BuildInverted(context);
-
- #define a(x) (CurrentMV->v[OF_##x])
- #define b(x) (CurrentP->v[OF_##x])
- #define verx (context->VertexBuffer[vertex].bx)
- #define very (context->VertexBuffer[vertex].by)
- #define verz (context->VertexBuffer[vertex].bz)
- #define verw (context->VertexBuffer[vertex].bw)
-
- u[0] = a(11)*verx + a(12)*very + a(13)*verz + a(14)*verw;
- u[1] = a(21)*verx + a(22)*very + a(23)*verz + a(24)*verw;
- u[2] = a(31)*verx + a(32)*very + a(33)*verz + a(34)*verw;
- u[3] = a(41)*verx + a(42)*very + a(43)*verz + a(44)*verw;
-
- verx = b(11)*u[0] + b(12)*u[1] + b(13)*u[2] + b(14)*u[3];
- very = b(21)*u[0] + b(22)*u[1] + b(23)*u[2] + b(24)*u[3];
- verz = b(31)*u[0] + b(32)*u[1] + b(33)*u[2] + b(34)*u[3];
- verw = b(41)*u[0] + b(42)*u[1] + b(43)*u[2] + b(44)*u[3];
-
- #undef a
- #undef b
- #undef verx
- #undef very
- #undef verz
- #undef verw
-
- #define ver(c) (context->VertexBuffer[vertex].Normal.c)
- #define a(x) (context->InvRot[x])
-
- // InvRot is row-major
- nx = ver(x)*a(0) + ver(y)*a(3) + ver(z)*a(6);
- ny = ver(x)*a(1) + ver(y)*a(4) + ver(z)*a(7);
- nz = ver(x)*a(2) + ver(y)*a(5) + ver(z)*a(8);
-
- #undef ver
- #undef a
-
-
- if (u[3] != 1.f)
- {
- u[0] /= u[3]; u[1] /= u[3]; u[2] /= u[3];
- }
-
- // nomalize unit vector
- ul = (float)sqrt((double)(u[0]*u[0] + u[1]*u[1] + u[2]*u[2]));
- if (ul == 0.f) return;
- u[0] /= ul; u[1] /= ul; u[2] /= ul;
-
-
- nu = nx*u[0] + ny*u[1]+nz*u[2]; nu *= 2.f;
-
- rx = u[0] - nx*nu;
- ry = u[1] - ny*nu;
- rz = u[2] - nz*nu;
-
-
- m = 0.5f / (float)sqrt((double)(rx*rx + ry*ry + (rz+1.f)*(rz+1.f)));
-
- s = rx*m + 0.5;
- t = ry*m + 0.5;
-
- if (context->TextureGenS_State == GL_TRUE)
- {
- context->VertexBuffer[vertex].v.u = context->w3dTexBuffer[context->CurrentBinding]->texwidth * s;
- }
- if (context->TextureGenT_State == GL_TRUE)
- {
- context->VertexBuffer[vertex].v.v = context->w3dTexBuffer[context->CurrentBinding]->texheight * t;
- }
- }
-
-
- INLINE void v_Transform(GLcontext context)
- {
- int i;
-
- if (context->TextureGenS_State == GL_TRUE || context->TextureGenT_State == GL_TRUE)
- {
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- v_GenTexCoords(context, i);
- }
- }
- else
- {
- if (context->CombinedValid == GL_FALSE)
- {
- m_CombineMatrices(context);
- }
- if (context->WOne_Hint == GL_FALSE)
- {
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- v_ApplyMatrixElCheapo(context, &(context->CombinedMatrix), i);
- }
- }
- else
- {
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- v_ApplyMatrixWOne(context, &(context->CombinedMatrix), i);
- }
- }
-
- }
- }
-
- INLINE void v_ToScreen(GLcontext context, int i)
- {
- float w = 1.0 / context->VertexBuffer[i].bw;
-
- context->VertexBuffer[i].v.x = context->ax + context->VertexBuffer[i].bx * w * context->sx;
- context->VertexBuffer[i].v.y = context->ay - context->VertexBuffer[i].by * w * context->sy;
- context->VertexBuffer[i].v.z = context->az + context->VertexBuffer[i].bz * w * context->sz;
- if (context->ZOffset_State == GL_TRUE)
- context->VertexBuffer[i].v.z += (W3D_Float)context->ZOffset;
- context->VertexBuffer[i].v.w = w;
- }
-
- void d_DrawPoints(GLcontext context)
- {
- }
-
- void d_DrawLines(GLcontext context)
- {
- }
-
- void d_DrawLineStrip(GLcontext context)
- {
- }
-
- #if 0
- void d_DumpPolygon(GLcontext context, MGLPolygon *poly)
- {
- int i;
- mykprintf("d_DumpPolygon: %d vertices\n", poly->numverts);
- for (i=0; i<poly->numverts; i++)
- {
- DUMP_VERTEX(context->VertexBuffer[poly->verts[i]]);
- }
- mykprintf("-- \n");
- }
- #endif
-
- void d_DrawTriangleFan(GLcontext context)
- {
- int i;
- GLubyte and_code, local_or, local_and;
- ULONG error;
- static W3D_Vertex **verts = NULL;
- static GLboolean visible[MGL_MAXVERTS]; // Should be enough...?
- static GLubyte complete[MGL_MAXVERTS]; // Ditto
- static W3D_TrianglesV tris;
- int triangle = 0;
-
- if (verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
- v_Transform(context); // Transform world to clipping coordinates
-
- and_code = 0xFF;
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- hc_CodePoint(&(context->VertexBuffer[i]));
- and_code &= context->VertexBuffer[i].outcode;
- }
-
- if (and_code) return;
-
- /*
- ** Up to now everything is like a polygon. Unlike a polygon, however,
- ** triangle fans and strips may be concave, and each individual triangle
- ** might be backfacing.
- **
- ** We calculate how many of the triangles are visible.
- */
- for (i=1,triangle=0; i<context->VertexBufferPointer - 1; i++, triangle++)
- {
- local_or = context->VertexBuffer[0].outcode
- | context->VertexBuffer[i].outcode
- | context->VertexBuffer[i+1].outcode;
-
- local_and = context->VertexBuffer[0].outcode
- & context->VertexBuffer[i].outcode
- & context->VertexBuffer[i+1].outcode;
-
- if (local_and == 0) // if the local and code is zero, we're not
- { // completely off screen.
- visible[triangle] = hc_DecideFrontface(context,
- &(context->VertexBuffer[0]),
- &(context->VertexBuffer[i]),
- &(context->VertexBuffer[i+1]), local_or);
- // if our local or codes are zero, we are completely
- // visible
- complete[triangle] = local_or;
- }
- else
- {
- visible[triangle] = GL_FALSE;
- }
- }
-
- /*
- ** Draw...
- ** There are three cases:
- **
- ** 1) Triangle is partially visible
- ** 2) Triangle is fully visible
- ** 3) Triangle is invisible
- **
- ** In case 1, we draw the triangle with clip_ClipAndDrawPoly.
- ** In case 2, we collect a triangle fan/strip of maximum length
- ** and draw that directly
- ** in case 3... WE IGNORE IT! HA!
- */
- triangle = 0; i=1;
-
- do
- {
- if (visible[triangle] == GL_FALSE) // case 3
- {
- triangle ++;
- i ++;
- }
- else
- {
- if (complete[triangle]) // case 1
- {
- static MGLPolygon poly;
- poly.numverts = 3;
- poly.verts[0] = 0;
- poly.verts[1] = i;
- poly.verts[2] = i + 1;
- // HERE
- hc_ClipAndDrawPoly(context, &poly, complete[triangle] );
- triangle++;
- i++;
- }
- else
- { // case 2 (the difficult part)
- int k=3;
- tris.vertexcount = 3;
- verts[0] = &(context->VertexBuffer[0].v);
- verts[1] = &(context->VertexBuffer[i].v);
- verts[2] = &(context->VertexBuffer[i+1].v);
- v_ToScreen(context, 0);
- v_ToScreen(context, i);
- v_ToScreen(context, i+1);
-
- triangle ++;
- i ++;
-
- while (complete[triangle]==0 && visible[triangle] && i<context->VertexBufferPointer - 1)
- {
- verts[k] = &(context->VertexBuffer[i+1].v);
- v_ToScreen(context, i+1);
- i++; k++; triangle++;
- tris.vertexcount ++;
- }
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.v = verts;
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriFan = %ld\n", error);
-
- }
- }
- } while (i<context->VertexBufferPointer-1);
-
- }
-
- void d_DrawTriangleStrip(GLcontext context)
- {
- int i;
- GLubyte and_code, local_or, local_and;
- ULONG error;
- static W3D_Vertex **verts = NULL;
- static GLboolean visible[MGL_MAXVERTS]; // Should be enough...?
- static GLubyte complete[MGL_MAXVERTS]; // Ditto
- static W3D_TrianglesV tris;
- int triangle = 0;
- GLenum CurrentFrontFace = context->CurrentFrontFace;
-
-
-
- if (verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
- v_Transform(context);
-
- and_code = 0xFF;
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- hc_CodePoint(&(context->VertexBuffer[i]));
- and_code &= context->VertexBuffer[i].outcode;
- }
-
- if (and_code) return;
-
- /*
- ** Up to now everything is like a polygon. Unlike a polygon, however,
- ** triangle fans and strips may be concave, and each individual triangle
- ** might be backfacing.
- **
- ** We calculate how many of the triangles are visible.
- */
- for (i=0,triangle=0; i<context->VertexBufferPointer - 2; i++, triangle++)
- {
- local_or = context->VertexBuffer[i+0].outcode
- | context->VertexBuffer[i+1].outcode
- | context->VertexBuffer[i+2].outcode;
-
- local_and = context->VertexBuffer[i+0].outcode
- & context->VertexBuffer[i+1].outcode
- & context->VertexBuffer[i+2].outcode;
-
- if (local_and == 0) // if the local and code is zero, we're not
- { // completely off screen.
- visible[triangle] = hc_DecideFrontface(context,
- &(context->VertexBuffer[i+0]),
- &(context->VertexBuffer[i+1]),
- &(context->VertexBuffer[i+2]), local_or);
- // if our local or codes are zero, we are completely
- // visible
- complete[triangle] = local_or;
- }
- else
- {
- visible[triangle] = GL_FALSE;
- }
-
- if (context->CurrentFrontFace == GL_CCW) context->CurrentFrontFace = GL_CW;
- else context->CurrentFrontFace = GL_CCW;
-
- }
- /*
- ** Draw...
- ** There are three cases:
- **
- ** 1) Triangle is partially visible
- ** 2) Triangle is fully visible
- ** 3) Triangle is invisible
- **
- ** In case 1, we draw the triangle with clip_ClipAndDrawPoly.
- ** In case 2, we collect a triangle fan/strip of maximum length
- ** and draw that directly
- ** in case 3... WE IGNORE IT! HA!
- */
- triangle = 0; i=0;
-
- context->CurrentFrontFace = CurrentFrontFace;
-
- do
- {
-
- if (visible[triangle] == GL_FALSE) // case 3
- {
- triangle ++;
- i ++;
- }
- else
- {
- if (complete[triangle]) // case 1
- {
- static MGLPolygon poly;
-
- poly.numverts = 3;
- poly.verts[0] = i + 0;
- poly.verts[1] = i + 1;
- poly.verts[2] = i + 2;
-
- hc_ClipAndDrawPoly(context, &poly, complete[triangle] );
- triangle++;
- i++;
- }
- else
- { // case 2 (the difficult part)
- int k=3;
- tris.vertexcount = 3;
- verts[0] = &(context->VertexBuffer[i+0].v);
- verts[1] = &(context->VertexBuffer[i+1].v);
- verts[2] = &(context->VertexBuffer[i+2].v);
- v_ToScreen(context, i);
- v_ToScreen(context, i+1);
- v_ToScreen(context, i+2);
- triangle ++;
- i ++;
-
- while (complete[triangle]==0 && visible[triangle] && i<context->VertexBufferPointer - 2)
- {
- verts[k] = &(context->VertexBuffer[i+2].v);
- v_ToScreen(context, i+2);
- i++; k++;
- triangle++;
- tris.vertexcount ++;
- }
-
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.v = verts;
- error = W3D_DrawTriStripV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriStrip = %ld\n", error);
-
- }
- }
- if (context->CurrentFrontFace == GL_CCW) context->CurrentFrontFace = GL_CW;
- else context->CurrentFrontFace = GL_CCW;
- } while (i<context->VertexBufferPointer - 2);
-
- context->CurrentFrontFace = CurrentFrontFace;
-
- }
-
- void d_DrawQuadStrip(GLcontext context)
- {
- int i;
- GLubyte or_code, and_code;
- ULONG error;
- static W3D_Vertex *verts[4];
- static W3D_TrianglesV tris;
-
- v_Transform(context);
-
- for (i=0; i<context->VertexBufferPointer-2; i+=2)
- {
- hc_CodePoint(&(context->VertexBuffer[i]));
- hc_CodePoint(&(context->VertexBuffer[i+1]));
- hc_CodePoint(&(context->VertexBuffer[i+2]));
- hc_CodePoint(&(context->VertexBuffer[i+3]));
-
- or_code = context->VertexBuffer[i+0].outcode
- | context->VertexBuffer[i+1].outcode
- | context->VertexBuffer[i+2].outcode
- | context->VertexBuffer[i+3].outcode;
-
- and_code = context->VertexBuffer[i+0].outcode
- & context->VertexBuffer[i+1].outcode
- & context->VertexBuffer[i+2].outcode
- & context->VertexBuffer[i+3].outcode;
-
- if (and_code) continue;
-
- if (hc_DecideFrontface(context, &(context->VertexBuffer[i]),
- &(context->VertexBuffer[i+1]),
- &(context->VertexBuffer[i+2]), or_code) == GL_FALSE) continue;
-
- if (or_code == 0)
- {
- v_ToScreen(context, i);
- v_ToScreen(context, i+1);
- v_ToScreen(context, i+2);
- v_ToScreen(context, i+3);
-
- verts[0] = &(context->VertexBuffer[i+0].v);
- verts[1] = &(context->VertexBuffer[i+1].v);
- verts[2] = &(context->VertexBuffer[i+3].v);
- verts[3] = &(context->VertexBuffer[i+2].v);
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.vertexcount = 4;
- tris.v = verts;
- if (context->ShadeModel == GL_FLAT)
- {
- W3D_SetCurrentColor(context->w3dContext, &(context->VertexBuffer[i].v.color));
- }
-
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriFan = %ld\n", error);
- }
- else
- {
- static MGLPolygon poly;
- poly.numverts = 4;
- poly.verts[0] = i;
- poly.verts[1] = i+1;
- poly.verts[2] = i+3;
- poly.verts[3] = i+2;
- if (context->ShadeModel == GL_FLAT)
- {
- W3D_SetCurrentColor(context->w3dContext, &(context->VertexBuffer[i].v.color));
- }
- hc_ClipAndDrawPoly(context, &poly, or_code);
- }
- }
- }
-
-
- void d_DrawQuads(GLcontext context)
- {
- int i;
- GLubyte or_code, and_code;
- ULONG error;
- static W3D_Vertex *verts[4];
- static W3D_TrianglesV tris;
-
-
- v_Transform(context);
-
- for (i=0; i<context->VertexBufferPointer; i+=4)
- {
- hc_CodePoint(&(context->VertexBuffer[i]));
- hc_CodePoint(&(context->VertexBuffer[i+1]));
- hc_CodePoint(&(context->VertexBuffer[i+2]));
- hc_CodePoint(&(context->VertexBuffer[i+3]));
-
- or_code = context->VertexBuffer[i+0].outcode
- | context->VertexBuffer[i+1].outcode
- | context->VertexBuffer[i+2].outcode
- | context->VertexBuffer[i+3].outcode;
-
- and_code = context->VertexBuffer[i+0].outcode
- & context->VertexBuffer[i+1].outcode
- & context->VertexBuffer[i+2].outcode
- & context->VertexBuffer[i+3].outcode;
-
- if (and_code) continue;
-
- if (hc_DecideFrontface(context, &(context->VertexBuffer[i]),
- &(context->VertexBuffer[i+1]),
- &(context->VertexBuffer[i+2]),or_code) == GL_FALSE) continue;
-
- if (context->ShadeModel == GL_FLAT)
- {
- W3D_SetCurrentColor(context->w3dContext, &(context->VertexBuffer[i].v.color));
- }
-
- if (or_code == 0)
- {
- v_ToScreen(context, i);
- v_ToScreen(context, i+1);
- v_ToScreen(context, i+2);
- v_ToScreen(context, i+3);
-
- verts[0] = &(context->VertexBuffer[i+0].v);
- verts[1] = &(context->VertexBuffer[i+1].v);
- verts[2] = &(context->VertexBuffer[i+2].v);
- verts[3] = &(context->VertexBuffer[i+3].v);
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.vertexcount = 4;
- tris.v = verts;
- #ifndef NODRAW
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriFan = %ld\n", error);
- #else
- printf("d_DrawQuads\n");
- DUMP_VERTEX(context->VertexBuffer[i+0]);
- DUMP_VERTEX(context->VertexBuffer[i+1]);
- DUMP_VERTEX(context->VertexBuffer[i+2]);
- DUMP_VERTEX(context->VertexBuffer[i+3]);
- printf("-----------------------------------\n");
- #endif
- #if 1
- if (error != W3D_SUCCESS) kprintf("[MiniGL::d_DrawQuads] Duh! Error %ld\n", error);
- #endif
- }
- else
- {
- static MGLPolygon poly;
- poly.numverts = 4;
- poly.verts[0] = i;
- poly.verts[1] = i+1;
- poly.verts[2] = i+2;
- poly.verts[3] = i+3;
- hc_ClipAndDrawPoly(context, &poly, or_code);
- }
- }
- }
-
- void d_DrawPolygon(GLcontext context)
- {
- int i;
- GLubyte or_code, and_code;
- MGLPolygon poly;
-
- v_Transform(context);
- or_code = 0; and_code = 0xFF;
-
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- hc_CodePoint(&(context->VertexBuffer[i]));
- or_code |= context->VertexBuffer[i].outcode;
- and_code &= context->VertexBuffer[i].outcode;
- poly.verts[i] = i;
- }
-
-
- if (and_code) return;
- #if 0
- if (hc_DecideFrontface(context, &(context->VertexBuffer[0]),
- &(context->VertexBuffer[1]),
- &(context->VertexBuffer[2]),or_code) == GL_FALSE) return;
- #endif
-
- poly.numverts = context->VertexBufferPointer;
-
- if (or_code == 0)
- {
- dh_DrawPolyFF(context, &poly);
- }
- else
- {
- hc_ClipAndDrawPolyFF(context, &poly, or_code);
- }
- }
-
- void d_DrawTriangles(GLcontext context)
- {
- int i;
- W3D_TriangleV tri;
- GLubyte or_code, and_code;
- ULONG error;
-
- v_Transform(context);
-
- for (i=0; i<context->VertexBufferPointer; i+=3)
- {
- hc_CodePoint(&(context->VertexBuffer[i]));
- hc_CodePoint(&(context->VertexBuffer[i+1]));
- hc_CodePoint(&(context->VertexBuffer[i+2]));
-
- or_code = context->VertexBuffer[i+0].outcode
- | context->VertexBuffer[i+1].outcode
- | context->VertexBuffer[i+2].outcode;
-
- and_code = context->VertexBuffer[i+0].outcode
- & context->VertexBuffer[i+1].outcode
- & context->VertexBuffer[i+2].outcode;
- if (and_code) continue;
-
- if (hc_DecideFrontface(context, &(context->VertexBuffer[i]),
- &(context->VertexBuffer[i+1]),
- &(context->VertexBuffer[i+2]),or_code) == GL_FALSE) continue;
-
-
- if (or_code == 0)
- {
- v_ToScreen(context, i);
- v_ToScreen(context, i+1);
- v_ToScreen(context, i+2);
-
- tri.v1 = &(context->VertexBuffer[i+0].v);
- tri.v2 = &(context->VertexBuffer[i+1].v);
- tri.v3 = &(context->VertexBuffer[i+2].v);
- tri.tex = context->w3dTexBuffer[context->CurrentBinding];
- tri.st_pattern = NULL;
- error = W3D_DrawTriangleV(context->w3dContext, &tri);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriangle = %ld\n", error);
- }
- else
- {
- static MGLPolygon poly;
- poly.numverts = 3;
- poly.verts[0] = i;
- poly.verts[1] = i+1;
- poly.verts[2] = i+2;
- hc_ClipAndDrawPoly(context, &poly, or_code);
- }
- }
- }
-
- /*
- ** A FlatFan is a triangle fan that is specified in device corrdinates and
- ** is drawn regardless of current matrix or other
- */
- void d_DrawFlatFan(GLcontext context)
- {
- ULONG error;
- int i;
- static W3D_Vertex *verts[MGL_MAXVERTS];
- static W3D_TrianglesV tris;
-
- for (i=0; i<context->VertexBufferPointer; i++)
- {
- verts[i] = &(context->VertexBuffer[i].v);
- context->VertexBuffer[i].v.x = (W3D_Float) context->VertexBuffer[i].bx;
- context->VertexBuffer[i].v.y = (W3D_Float) context->VertexBuffer[i].by;
- context->VertexBuffer[i].v.z = (W3D_Double)context->VertexBuffer[i].bz;
- context->VertexBuffer[i].v.w = (W3D_Float) context->VertexBuffer[i].bw;
- }
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.v = verts;
- tris.vertexcount = context->VertexBufferPointer;
- #ifndef NODRAW
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriFanV = %ld\n", error);
- #endif
- }
-
- void dh_DrawPoly(GLcontext context, MGLPolygon *poly)
- {
- int i;
- ULONG error;
- static W3D_Vertex *verts[MGL_MAXVERTS];
- static W3D_TrianglesV tris;
-
- for (i=0; i<poly->numverts; i++)
- {
- v_ToScreen(context, poly->verts[i]);
- verts[i] = &(context->VertexBuffer[poly->verts[i]].v);
- }
-
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.vertexcount = poly->numverts;
- tris.v = verts;
- #ifndef NODRAW
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriFan = %ld\n", error);
- #endif
- }
-
- inline GLfloat dh_AreaSign(GLcontext context, MGLPolygon *poly)
- {
- int i,j;
- GLfloat area=0.0;
- #define x(i) (context->VertexBuffer[poly->verts[i]].v.x)
- #define y(i) (context->VertexBuffer[poly->verts[i]].v.y)
-
- for (i=0; i<poly->numverts; i++)
- {
- j=(i+1)%(poly->numverts);
- area += (x(i)*y(j) - x(j)*y(i));
- }
-
- #undef x
- #undef y
-
- return area;
- }
-
- void dh_DrawPolyFF(GLcontext context, MGLPolygon *poly)
- {
- int i;
- ULONG error;
- static W3D_Vertex *verts[MGL_MAXVERTS];
- static W3D_TrianglesV tris;
- GLfloat area;
-
- for (i=0; i<poly->numverts; i++)
- {
- v_ToScreen(context, poly->verts[i]);
- verts[i] = &(context->VertexBuffer[poly->verts[i]].v);
- }
-
- if (context->CullFace_State == GL_TRUE)
- {
- area = dh_AreaSign(context, poly);
-
- if (context->CurrentFrontFace == GL_CW) area *= -1.f;
- if (area < 0.0) return;
- }
-
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
- tris.vertexcount = poly->numverts;
- tris.v = verts;
- #ifndef NODRAW
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
- if (error != W3D_SUCCESS) kprintf("W3D_DrawTriFan = %ld\n", error);
- #endif
- }
-
-